import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;


public class Hierarchy {
	
	
	public Category Root;
	public Category Sports;
	public Category Health;
	public Category Computers;
	public Category Hardware;
	public Category Programming;
	public Category Fitness;
	public Category Diseases;
	public Category Basketball;
	public Category Soccer;
	
	public HashMap<String, Category> catMap=new HashMap<String, Category>();
	
	public HashMap<String, List<String>> queryUrlMap= new HashMap<String, List<String>>();
	
	public Hierarchy( ){
		
		 this.Root= new Category("Root");
		 this.Sports= new Category("Sports");
		 this.Health= new Category("Health");
		 this.Computers= new Category("Computers");
	     this.Hardware=new Category("Hardware");
		 this.Programming=new Category("Programming");
		 this.Fitness= new Category("Fitness");
		 this.Diseases= new Category("Diseases");
		 this.Basketball= new Category("Basketball");
		 this.Soccer= new Category("Soccer");
		 
		 Root.addChild(Health);		    Health.addParent(Root);
		 Root.addChild(Computers);		Computers.addParent(Root);
		 Root.addChild(Sports);			Sports.addParent(Root);
	 
		 Health.addChild(Fitness); 		Fitness.addParent(Health); 
		 Health.addChild(Diseases);        Diseases.addParent(Health);
	 
		 Computers.addChild(Programming);	Computers.addChild(Hardware);
		 Programming.addParent(Computers);	 Hardware.addParent(Computers);
	 
		 Sports.addChild(Soccer); Sports.addChild(Basketball); 
		 Soccer.addParent(Sports); Soccer.addParent(Sports);
	 
		 catMap.put("Root", Root);
		 catMap.put("Sports", Sports);
		 catMap.put("Computers", Computers);
		 catMap.put("Health", Health);
		 catMap.put("Basketball", Basketball);
		 catMap.put("Soccer", Soccer);
		 catMap.put("Fitness", Fitness);
		 catMap.put("Diseases", Diseases);
		 catMap.put("Programming", Programming);
		 catMap.put("Hardware",Hardware);
	}
	
    public void buildProbes() throws IOException{
    	
    	Category R=Root;
    	Category C;
    	Queue<Category> Q = new LinkedList <Category>();
    	
    	Q.add(Root);
    	
    	while(! Q.isEmpty()){
    		
    		C=Q.poll();
    		
    		Q.addAll(C.children);
    		//System.out.println(C.name);
    		
    		if (! C.children.isEmpty()){
    		
    			String line;
    			BufferedReader br; 
    			
    			br = new BufferedReader(new FileReader(C.name+".txt"));
    			//System.out.println(C.name);
    			line=br.readLine(); 
    			
    			while(line!=null){
            	
    				String[] queryT= line.split("\\s");
    				String query=queryT[1];
    				for(int i=2;i<queryT.length;i++){
    					query=query+"%20"+queryT[i];
    				} 				
    				catMap.get(queryT[0]).probeQueries.add(query); 
            	    
    				line=br.readLine();
    			}
            
    		
    		}
    	}

    	
    }
    public int calCoverage(Category D ,String url) throws IOException, SAXException, ParserConfigurationException{
    	int count=0;
    	String api = " ";
    	
    
		for( String s:D.probeQueries){
			
    		ReqResult result=new ReqResult();
    		result=XML.reqResp(s,api, url);
    		count+=result.getCount();
    		if(!result.getURLList().isEmpty()){
    			
    			queryUrlMap.put(result.getQuery(),result.getURLList());
    		}
    	}
    	
    	D.eCoverage=count;
    	return count;
    }
	public void calSpecifity(Category D, String url,double pspec, int totalCount){
		
		D.eSpecifify = pspec*(((double)D.eCoverage)/((double)totalCount));
		
		System.out.println(D.name+"\t"+D.eSpecifify+"\t"+D.eCoverage+"\t"+totalCount+"\t"+pspec);
	}
	
public List<Category> myClass(Category C, String url, int coverage, double specifity ) throws IOException, SAXException, ParserConfigurationException{
		
		List<Category> result=new ArrayList<Category> ();
		if(C.children.isEmpty()){
			result.add(C);
			return result;
		}
		else{
			int totalCount=0;
			
				for(Category D:C.children){
					
						totalCount=totalCount+calCoverage(D, url);		
				}
				
				for(Category D:C.children){
					
				     calSpecifity(D, url, C.eSpecifify,totalCount);
				}
				
				for(Category D:C.children){
					
					if(D.eSpecifify>specifity && D.eCoverage>coverage){
						
						result.addAll(myClass(D, url,coverage, specifity));
					}
				}
				if(result.isEmpty()){
					
					result.add(C);
				}
				
				return result;
				
		}
	
	}
	
	
	public static void main(String args[]) throws IOException, SAXException, ParserConfigurationException{
		
		List <Category> results=new ArrayList<Category>();
		HashMap<Category, Set<String>> queryMap=new HashMap<Category,Set<String>>();
		Hierarchy H = new Hierarchy();
		
		H.buildProbes();
		H.Root.eSpecifify=1.0;
		
		
		results=H.myClass(H.Root, "diabetes.org", 200, 0.6);
		
		for(Category s:results){
			
			System.out.println(s.name);
		}
     
		queryMap=DocumentSampling.sample(H, results, "helloworld");
		
		for(String s: H.queryUrlMap.keySet()){
			
			System.out.println(s+":\t"+H.queryUrlMap.get(s));
		}
		
		DocumentSampling.buildTextDataBase(H.queryUrlMap, queryMap.get(H.Root));
		
	}
}
